<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>computed，watch</title>
</head>
<body>
    <div id="app">
        全选反选<input type="checkbox" v-model="checkAll">
        <hr>
        <input type="checkbox" v-for="item in checks" v-model="item.check">
        <hr>

        {{timer | format('YYYY:MM:DD hh:mm:ss')}}
        {{money | fixed(2)}}
        <hr>

        <div v-click-outside="hideFn">
            <input type="text" @focus="showFn">
            <div v-if="show">显示内容</div>
        </div>
        <input type="text" v-focus>
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script src="node_modules/moment/moment.js"></script>
    <script>
        //格式化时间插件  npm install moment
        //全局过滤器
        //过滤器就是将原数据进行格式化显示，而不改变原数据
        Vue.filter('format',function(timer,formatter){
            //filter 没有this
            return moment(timer).format(formatter)
        })
        let vm = new Vue({
            el:'#app',
            data(){
                return {
                    msg:{a:1},
                    checks:[{check:true},{check:true},{check:true}],
                    timer:1734512832100,
                    money:'28',
                    show:false
                }
            },
            filters:{
                //局部过滤器
                fixed(value,num){
                    return  '￥' + Number(value).toFixed(num)
                }
            },
            computed:{
                checkAll:{
                    get(){//取值执行get方法
                        return this.checks.every(item=>item.check)//every有一项是false就返回false
                    },
                    set(newValue){
                        this.checks.forEach(item=>{
                            item.check = newValue;
                        })
                    }
                }
            },
            directives:{
                //指令有生命周期 钩子函数（默认写成函数的话：bind + update）
                //bind      当指令绑定上的时候，会执行一次
                //inserted  插入的时候
                //update    当引用的数据变化时会执行一个钩子
                //componentUpdate  更新完成之后调用
                //unbind    只调用一次，解绑的时候
                //函数的形式
                // clickOutside(el,bindings,vnode){
                //     // console.log(el,bindings,vnode.context)
                //     document.addEventListener('click',function(e){
                //         if(!el.contains(e.target)){             //el.contains
                //             let method = bindings.expression;   //bindings.expression
                //             //vm.hideFn();
                //             vnode.context[method]()             //vnode.context
                //         }
                //     })
                // },
                //对象的形式
                clickOutside:{
                    bind(el,bindings,vnode){
                        el.handler = (e)=>{
                            if(!el.contains(e.target)){
                                //因为是表达式所以用expression
                                vnode.context[bindings.expression]()
                            }
                        }
                        document.addEventListener('click',el.handler)
                    },
                    unbind(el){
                        document.removeEventListener('click',el.handler)
                    }
                },
                //focus(el){el.focus()},//这时既没更新也没绑定，也没放到页面中所以不生效
                focus:{
                    // bind(el){
                    //     Vue.nextTick(()=>{
                    //         el.focus()
                    //     })
                    // }
                    inserted(el){ //插入时的生命周期
                        el.focus()
                    }
                }
            },
            methods:{
                fn(){
                    console.log(123)
                },
                showFn(){
                    this.show = true;
                },
                hideFn(){
                    this.show = false;
                }
            },
            //watch三种写法：函数，对象，字符串
            watch:{
                msg:[
                {
                    handler(newValue,oldValue){
                        //如果是对象类型无法获取老值
                        console.log(newValue,oldValue)
                    },
                    deep:true //在内部再去对这个对象取值
                },
                {
                    handler(newValue,oldValue){
                        console.log(newValue,oldValue)
                    },
                    immediate:true //立即执行，用的少，一般会直接写到mounted
                },
                'fn'
                ]
            }
        })
        setTimeout(()=>{
            // vm.msg.a = 2
            vm.msg = 100
        },1000)
        //计算属性和watch区别（都是一个watcher）
        //计算属性内部不会立马获取值，只有取值的时候才执行（有缓存的，如果依赖的数据不发生变化，则不更新结果）
        //watch默认会在内部先执行，他要算出一个老值来，如果数据变换会执行回调函数
    </script>
</body>
</html>